import { restArguments } from '../collections/invoke'
import isObject from '../object/isObject';
import isFunction from '../object/isFunction';
export var Ctor = function () { };
export function baseCreate(prototype) {
  if (!isObject(prototype)) return {}
  if (Object.create) return Object.create(prototype)
  Ctor.prototype = prototype
  var result = new Ctor
  Ctor.prototype = null
  return result
}


export function executeBound(sourceFunc, boundFunc, context, callingContext, args) {
  if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
  var self = baseCreate(sourceFunc.prototype);
  var result = sourceFunc.apply(self, args);
  if (isObject(result)) return result;
  return self;
}

export default restArguments(function (func, context, args) {
  if (!isFunction(func)) throw new TypeError('Bind must be called on a function');
  var bound = restArguments(function (callArgs) {
    return executeBound(func, bound, context, this, args.concat(callArgs));
  });
  return bound;
});

Ctor.prototype.bind2 = function (context = globalThis, ...args) {
  const self: Function = this
  return function (...args1) {
    return self.apply(context, [...args, ...args1])
  }
}
